home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Revolution - Das Atari CD Magazin 1997
/
Revolution - Das Atari CD Magazin 1.iso
/
software
/
anwendng
/
qed_397
/
sourcen
/
block.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-12-29
|
16KB
|
814 lines
#include "global.h"
#include "clipbrd.h"
#include "edit.h"
#include "obj.h"
#include "rsc.h"
#include "set.h"
#include "trash.h"
#include "block.h"
/* lokale Prototypen *******************************************************/
LOCAL VOID block_demark (TEXTP t_ptr);
LOCAL BOOLEAN tab_ok (LINEP a, BOOLEAN tab, WORD tabsize);
LOCAL VOID block_setzen (TEXTP t_ptr);
LOCAL BOOLEAN block_delete (TEXTP t_ptr, RINGPTR t);
LOCAL BOOLEAN block_einsetzen(TEXTP t_ptr, RINGPTR t);
/* lokale Variablen ********************************************************/
LOCAL WORD undo_anf_x, undo_end_x;
LOCAL LONG undo_anf_y, undo_end_y;
VOID blk_mark_all(TEXTP t_ptr)
{
LINEP col;
if (t_ptr->block)
block_demark(t_ptr);
col = FIRST(&t_ptr->text);
t_ptr->x1 = 0;
t_ptr->p1 = col;
t_ptr->z1 = 0;
col = LAST(&t_ptr->text);
t_ptr->x2 = col->len;
t_ptr->p2 = col;
t_ptr->z2 = t_ptr->text.lines-1;
t_ptr->block_dir = FALSE; /* Anfang und Ende nicht vertauscht */
block_setzen(t_ptr);
make_chg(t_ptr->link,BLK_CHANGE,0);
make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z2);
}
VOID blk_mark_word(TEXTP t_ptr) /* Wort unter dem Cursor markieren */
{
WORD pos,len;
UBYTE *str;
pos = t_ptr->xpos;
str = TEXT(t_ptr->cursor_line)+pos;
len = t_ptr->cursor_line->len;
while(pos>=0 && setin(t_ptr->loc_opt->wort_set,*str))
{
pos--;
str--;
}
str++; pos++;
t_ptr->xpos = pos;
blk_mark(t_ptr, 0);
while(pos<=len && setin(t_ptr->loc_opt->wort_set,*str))
{
pos++;
str++;
}
t_ptr->xpos = pos;
blk_mark(t_ptr, 1);
restore_edit();
}
VOID get_blk_mark(TEXTP t_ptr, LONG *y, WORD *x)
{
if (t_ptr->block_dir)
{
*y = t_ptr->z2;
*x = t_ptr->x2;
}
else
{
*y = t_ptr->z1;
*x = t_ptr->x1;
}
}
VOID blk_mark(TEXTP t_ptr, WORD marke)
/* Blockstart und -ende setzen */
/* marke : 0 und 1 */
{
if (marke==0) /* Anfang setzten */
{
blk_demark(t_ptr);
t_ptr->p2 = t_ptr->p1 = t_ptr->cursor_line;
t_ptr->z2 = t_ptr->z1 = t_ptr->ypos;
t_ptr->x2 = t_ptr->x1 = t_ptr->xpos;
t_ptr->block_dir = FALSE;
}
else /* Block aufziehen */
{
if (t_ptr->block_dir)
{
if (t_ptr->p1 == t_ptr->cursor_line && t_ptr->x1 == t_ptr->xpos)
return; /* Keine Änderung */
if (t_ptr->block)
{
block_demark(t_ptr);
make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z1);
make_chg(t_ptr->link,BLK_CHANGE,t_ptr->ypos);
}
else
{
make_chg(t_ptr->link,BLK_CHANGE,t_ptr->ypos);
make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z2);
}
t_ptr->p1 = t_ptr->cursor_line;
t_ptr->x1 = t_ptr->xpos;
t_ptr->z1 = t_ptr->ypos;
}
else
{
if (t_ptr->p2==t_ptr->cursor_line && t_ptr->x2==t_ptr->xpos)
return; /* Keine Änderung */
if (t_ptr->block)
{
block_demark(t_ptr);
make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z2);
make_chg(t_ptr->link,BLK_CHANGE,t_ptr->ypos);
}
else
{
make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z1);
make_chg(t_ptr->link,BLK_CHANGE,t_ptr->ypos);
}
t_ptr->p2 = t_ptr->cursor_line;
t_ptr->x2 = t_ptr->xpos;
t_ptr->z2 = t_ptr->ypos;
}
block_setzen(t_ptr);
}
}
VOID blk_demark(TEXTP t_ptr)
{
if (t_ptr->block)
{
block_demark(t_ptr);
make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z1);
make_chg(t_ptr->link,BLK_CHANGE,t_ptr->z2);
t_ptr->p1 = t_ptr->p2 = NULL;
t_ptr->z1 = t_ptr->z2 = -1;
}
}
VOID blk_copy(TEXTP t_ptr, BOOLEAN add)
/* Kopiert Block aus einem Text auf das Clipbrd */
{
RING t;
if (!t_ptr->block)
return;
if (!ist_mem_frei())
return;
block_copy(t_ptr,&t);
if (add)
clip_add_text(&t);
else
clip_takes_text(&t);
}
VOID line_copy(TEXTP t_ptr, BOOLEAN add)
/* Kopiert aktuelle Zeile auf das Clipboard */
{
LINEP col = t_ptr->cursor_line;
WORD old_x;
old_x = t_ptr->xpos;
t_ptr->xpos = 0;
blk_mark(t_ptr,0);
if (IS_LAST(col))
{
t_ptr->xpos = col->len;
blk_mark(t_ptr,1);
t_ptr->xpos = old_x;
}
else
{
NEXT(col);
t_ptr->cursor_line = col;
blk_mark(t_ptr,1);
VORG(col);
t_ptr->cursor_line = col;
t_ptr->xpos = old_x;
}
blk_copy(t_ptr,add);
blk_demark(t_ptr);
}
VOID blk_paste(TEXTP t_ptr, RINGP t)
/* Setzt den Text t im Text an Cursorposition ein */
/* Der Cursor steht anschließend dahinter */
/* Ist ein Block da, wird er gelöscht */
{
if (!ist_mem_frei())
return;
blk_delete(t_ptr);
block_einsetzen(t_ptr, t);
t_ptr->moved++;
add_undo(BLK_PASTE);
}
VOID blk_delete(TEXTP t_ptr)
{
RING t;
if(!t_ptr->block)
return;
if (!ist_mem_frei())
return;
if (!block_delete(t_ptr, &t))
return;
trash_takes_text(&t);
t_ptr->moved++;
add_undo(BLK_DEL);
}
VOID blk_cut(TEXTP t_ptr, BOOLEAN add)
{
RING t, t2;
if (!t_ptr->block)
return;
if (!ist_mem_frei())
return;
if (!block_delete(t_ptr, &t))
return;
init_textring(&t2);
if (doppeln(&t,&t2))
{
if (add)
clip_add_text(&t2);
else
clip_takes_text(&t2);
}
undo_takes_text(&t);
t_ptr->moved++;
add_undo(BLK_CUT);
}
VOID blk_undo(TEXTP t_ptr, WORD undo)
{
RING t;
if (!ist_mem_frei())
return;
if (undo==BLK_PASTE || undo==BLK_PASTE_TRASH)
/* Block muß wieder gelöscht werden */
{
blk_demark(t_ptr);
t_ptr->p1 = get_line(&t_ptr->text,undo_anf_y);
t_ptr->z1 = undo_anf_y;
t_ptr->x1 = undo_anf_x;
t_ptr->p2 = get_line(&t_ptr->text,undo_end_y);
t_ptr->z2 = undo_end_y;
t_ptr->x2 = undo_end_x;
block_setzen(t_ptr);
block_delete(t_ptr, &t); /* Block ausschneiden und als Undotext */
if (undo==BLK_PASTE)
{
undo_takes_text(&t);
add_undo(BLK_CUT);
}
else
{
trash_takes_text(&t);
add_undo(BLK_DEL);
}
t_ptr->moved++;
}
if (undo==BLK_CUT) /* Block muß wieder eingefügt werden */
{
RINGP tp;
t_ptr->xpos = undo_anf_x;
tp = get_undo_text();
block_einsetzen(t_ptr, tp);
add_undo(BLK_PASTE);
}
if (undo==BLK_DEL) /* Text aus Papierkorb wieder einsetzten */
{
RINGP tp;
t_ptr->xpos = undo_anf_x;
tp = &(get_text(itrash)->text);
block_einsetzen(t_ptr, tp);
add_undo(BLK_PASTE_TRASH);
}
}
VOID blk_right(TEXTP t_ptr, BOOLEAN onechar)
{
LINEP lauf;
LONG y, ende;
BOOLEAN t = t_ptr->loc_opt->tab;
if (!t_ptr->block)
return;
lauf = t_ptr->p1;
y = t_ptr->z1;
ende = t_ptr->z2;
if (y < ende)
{
WORD anz, i;
UBYTE c, *str;
if (t)
{
anz = 1;
c = '\t';
}
else
{
anz = t_ptr->loc_opt->tabsize;
c = ' ';
}
if (onechar)
{
anz = 1;
c = ' ';
}
t_ptr->moved++;
clr_undo();
if (t_ptr->x1>0) t_ptr->x1 += anz;
while (y<ende || t_ptr->x2>0)
{
if (lauf->len+anz>MAX_LINE_LEN)
{
inote(1, TOOLONG, MAX_LINE_LEN);
break;
}
str = REALLOC(&lauf,0,anz);
for (i=anz; (--i)>=0; )
*str++ = c;
if (y==t_ptr->z1)
t_ptr->p1 = lauf;
if (y==ende)
{
t_ptr->p2 = lauf;
break;
}
NEXT(lauf);
y++;
}
if (t_ptr->x2>0) t_ptr->x2 += anz;
t_ptr->cursor_line = get_line(&t_ptr->text,t_ptr->ypos);
make_chg(t_ptr->link,TOTAL_CHANGE,t_ptr->z1);
}
}
VOID blk_left(TEXTP t_ptr, BOOLEAN onechar)
{
LINEP lauf;
LONG y, ende;
BOOLEAN t = t_ptr->loc_opt->tab;
WORD ts = t_ptr->loc_opt->tabsize;
if (!t_ptr->block)
return;
if (!ist_mem_frei())
return;
lauf = t_ptr->p1;
y = t_ptr->z1;
ende = t_ptr->z2;
if (y < ende)
{
WORD anz;
if (t)
anz = 1;
else
anz = ts;
/*
Rene, kommt noch!
if (onechar)
{
anz = ts = 1;
t = FALSE;
}
*/
t_ptr->moved++;
clr_undo();
if (tab_ok(lauf,t,ts))
{
if (t_ptr->x1 <= anz)
t_ptr->x1 = 0;
else
t_ptr->x1 -= anz;
}
while (y < ende || t_ptr->x2 > 0)
{
if (tab_ok(lauf,t,ts))
{
REALLOC(&lauf, 0, -anz);
if (y == t_ptr->z1)
t_ptr->p1 = lauf;
if (y == ende)
t_ptr->p2 = lauf;
}
if (y == ende)
break;
NEXT(lauf);
y++;
}
if (tab_ok(lauf,t,ts))
{
if (t_ptr->x2 <= anz)
t_ptr->x2 = 0;
else
t_ptr->x2 -= anz;
}
t_ptr->cursor_line = get_line(&t_ptr->text, t_ptr->ypos);
make_chg(t_ptr->link, POS_CHANGE, 0);
make_chg(t_ptr->link, TOTAL_CHANGE, t_ptr->z1);
}
}
/*-------------------------------------------------------------------*/
VOID str_ch_uprlwr (UBYTE *line)
{
UBYTE stra[2],strb[2];
stra[1] = strb[1] = EOS;
while (*line != EOS)
{
stra[0] = *line;
strb[0] = *line;
str_upper(stra);
str_lower(strb);
if (stra[0] == *line)
*line = strb[0];
else
*line = stra[0];
line++;
}
}
VOID strcap (UBYTE *line, SET wort_set)
{
UBYTE stra[2],strb[2];
stra[1] = strb[1] = EOS;
stra[0] = *line;
if (setin(wort_set,stra[0]))
{
str_upper(stra);
*line=stra[0];
}
line++;
while (*line != EOS)
{
strb[0] = *(line-1);
if (!setin(wort_set,strb[0]))
{
stra[0] = *line;
if (setin(wort_set,stra[0]))
{
str_upper(stra);
*line=stra[0];
}
}
line++;
}
}
VOID blk_upplow(TEXTP t_ptr, int type)
{
LINEP lauf;
LONG y, ende;
if (!t_ptr->block)
return;
lauf = t_ptr->p1;
y = t_ptr->z1;
ende = t_ptr->z2;
if (y <= ende)
{
UBYTE *Tline, c;
t_ptr->moved++;
clr_undo();
while (y < ende || t_ptr->x2 > 0)
{
if (y == t_ptr->z1)
Tline = TEXT(lauf)+t_ptr->x1;
else
Tline = TEXT(lauf);
if (y == ende)
{
c = *(TEXT(lauf)+t_ptr->x2);
*(TEXT(lauf)+t_ptr->x2) = EOS; /* Zeile unterbrechen */
}
switch (type)
{
case BLK_UPPER:
str_upper (Tline);
break;
case BLK_LOWER :
str_lower (Tline);
break;
case BLK_CH_UPLO :
str_ch_uprlwr (Tline);
break;
case BLK_CAPS :
str_lower (Tline);
strcap (Tline,t_ptr->loc_opt->wort_set);
break;
}
if (y == ende)
{
*(TEXT(lauf)+t_ptr->x2) = c; /* Zeile restaurieren */
break;
}
NEXT(lauf);
y++;
}
t_ptr->moved++;
make_chg(t_ptr->link, POS_CHANGE, 0);
make_chg(t_ptr->link, TOTAL_CHANGE, t_ptr->z1);
}
}
/*----------------------------------------------------------------*/
LOCAL VOID block_demark(TEXTP t_ptr)
{
t_ptr->block = FALSE;
t_ptr->cursor = TRUE;
}
LOCAL BOOLEAN tab_ok(LINEP a, BOOLEAN tab, WORD tabsize)
{
WORD anz;
UBYTE *str;
if (tab)
{
if (a->len==0) return(FALSE);
str = TEXT(a);
if (*str!='\t') return(FALSE);
}
else
{
anz = tabsize;
if (a->len<anz) return(FALSE);
str = TEXT(a);
while ((--anz)>=0)
{
if (*str++!=' ') return(FALSE);
}
}
return(TRUE);
}
LOCAL VOID block_setzen(TEXTP t_ptr)
{
if (t_ptr->p1 == t_ptr->p2 && t_ptr->x1 == t_ptr->x2)
return;
if (t_ptr->z1 > t_ptr->z2) /* Richtung falsch => tauschen */
{
LINEP col;
LONG l;
WORD i;
t_ptr->block_dir ^= TRUE;
i = t_ptr->x1;
t_ptr->x1 = t_ptr->x2;
t_ptr->x2 = i;
col = t_ptr->p1;
t_ptr->p1 = t_ptr->p2;
t_ptr->p2 = col;
l = t_ptr->z1;
t_ptr->z1 = t_ptr->z2;
t_ptr->z2 = l;
}
else if (t_ptr->z1 == t_ptr->z2 && t_ptr->x1 > t_ptr->x2)
{
WORD xw;
t_ptr->block_dir ^= TRUE;
xw = t_ptr->x1;
t_ptr->x1 = t_ptr->x2;
t_ptr->x2 = xw;
}
t_ptr->block = TRUE;
t_ptr->cursor = FALSE;
}
LOCAL BOOLEAN block_delete(TEXTP t_ptr, RINGP t)
{
LINEP b_anf_col, b_end_col;
LONG lines;
b_anf_col = t_ptr->p1;
b_end_col = t_ptr->p2;
if (b_end_col->len-t_ptr->x2+t_ptr->x1>MAX_LINE_LEN)
{
inote(1, TOOLONG, MAX_LINE_LEN);
return(FALSE);
}
/* Cursor an den Blockanfang bringen */
t_ptr->ypos = t_ptr->z1;
t_ptr->xpos = t_ptr->x1;
undo_anf_y = t_ptr->z1;
undo_anf_x = t_ptr->x1;
undo_y = t_ptr->ypos; /* globale Merkvariable */
lines = t_ptr->z2-t_ptr->z1+1;
if (lines==1) /* ganz ohne Zeilenumbruch */
{
WORD len = t_ptr->x2-t_ptr->x1;
LINEP b;
init_textring(t);
b = FIRST(t);
INSERT(&b, 0, len, TEXT(b_anf_col)+t_ptr->x1);
REALLOC(&b_anf_col, t_ptr->x1, -len);
t_ptr->cursor_line = b_anf_col;
}
else
{
col_split(&b_end_col,t_ptr->x2);
NEXT(b_end_col);
col_split(&b_anf_col,t_ptr->x1);
/* Block ausschneiden */
FIRST(t) = b_anf_col->nachf;
b_anf_col->nachf->vorg = &t->head;
LAST(t) = b_end_col->vorg;
b_end_col->vorg->nachf = &t->tail;
t->lines = lines;
/* Kette wieder schließen */
b_anf_col->nachf = b_end_col;
b_end_col->vorg = b_anf_col;
col_concate(&b_anf_col);
t_ptr->cursor_line = b_anf_col;
}
if (lines==1)
{
make_chg(t_ptr->link,POS_CHANGE, 0);
make_chg(t_ptr->link,LINE_CHANGE, undo_y);
}
else if (lines==2)
{
make_chg(t_ptr->link,POS_CHANGE, 0);
make_chg(t_ptr->link,LINE_CHANGE, undo_y);
make_chg(t_ptr->link,SCROLL_UP, undo_y+1);
}
else
{
make_chg(t_ptr->link,POS_CHANGE, 0);
make_chg(t_ptr->link,TOTAL_CHANGE,t_ptr->z1);
}
t_ptr->block = FALSE;
t_ptr->cursor = TRUE;
t_ptr->text.lines -= (lines-1);
return(TRUE);
}
VOID block_copy(TEXTP t_ptr, RINGP t)
{
LINEP a, lauf;
init_textring(t);
a = FIRST(t); /* erste Zeile */
lauf = t_ptr->p1; /* Blockstart */
if (lauf==t_ptr->p2) /* nur eine Zeile */
{
INSERT(&a, 0, t_ptr->x2-t_ptr->x1, TEXT(lauf)+t_ptr->x1);
a->info |= ABSATZ;
}
else
{
LINEP new, ende;
/* erste Zeile teilweise */
INSERT(&a, 0, lauf->len-t_ptr->x1, TEXT(lauf)+t_ptr->x1);
if (lauf->info&ABSATZ) a->info |= ABSATZ;
else a->info &= (~ABSATZ);
ende = t_ptr->p2;
NEXT(lauf);
NEXT(a); /* TAIL im neuen Text */
while (lauf!=ende && ist_mem_frei())
{
new = new_col_w(TEXT(lauf), lauf->len);
if (lauf->info&ABSATZ) new->info |= ABSATZ;
col_insert(a->vorg,new);
t->lines++;
NEXT(lauf);
}
new = new_col_w(TEXT(lauf),t_ptr->x2); /* letzte Zeile teilweise */
new->info |= ABSATZ;
col_insert(a->vorg,new);
t->lines++;
}
}
/* Der Cursor von t_ptr steht anschließend hinter der Einfügung */
LOCAL BOOLEAN block_einsetzen(TEXTP t_ptr, RINGP in)
{
RING t;
LINEP a,b,
col = t_ptr->cursor_line;
LONG len;
a = FIRST(in);
b = LAST(in);
if ((a!=b &&
(t_ptr->xpos+a->len>MAX_LINE_LEN ||
b->len+(col->len-t_ptr->xpos)>MAX_LINE_LEN)) ||
(a==b &&
col->len+a->len>MAX_LINE_LEN))
{
inote(1, TOOLONG, MAX_LINE_LEN);
return(FALSE);
}
init_textring(&t);
doppeln(in, &t);
a = FIRST(&t);
b = LAST(&t);
if (t.lines==1) /* Ganz ohne Zeilenveränderung */
make_chg(t_ptr->link,LINE_CHANGE,t_ptr->ypos);
else if(t.lines==2) /* Einen Zeilenumbruch */
{
make_chg(t_ptr->link,SCROLL_DOWN,t_ptr->ypos+1);
make_chg(t_ptr->link,LINE_CHANGE,t_ptr->ypos);
make_chg(t_ptr->link,LINE_CHANGE,t_ptr->ypos+1);
}
else
{
make_chg(t_ptr->link,TOTAL_CHANGE,t_ptr->ypos);
}
len = t.lines-1;
t_ptr->text.lines += len;
undo_anf_y = t_ptr->ypos;
undo_anf_x = t_ptr->xpos;
undo_end_y = undo_anf_y+len;
undo_end_x = b->len;
undo_y = t_ptr->ypos; /* globale Merkvariable */
if (len==0)
{
INSERT(&col, t_ptr->xpos, a->len, TEXT(a));
undo_end_x += t_ptr->xpos;
kill_textring(&t);
}
else
{
col_split(&col,t_ptr->xpos); /* Textzeile splitten */
col->nachf->vorg = b; /* Block einfügen unten */
b->nachf = col->nachf;
col_concate(&b); /* Untere letzte Zeile */
col->nachf = a; /* Block einfügen oben */
a->vorg = col;
col_concate(&col);
}
/* Cursor hinter Einfügung */
t_ptr->cursor_line = get_line(&t_ptr->text,undo_end_y);
t_ptr->ypos = undo_end_y;
t_ptr->xpos = undo_end_x;
t_ptr->moved++;
make_chg(t_ptr->link, POS_CHANGE, 0);
return(TRUE);
}
VOID block_info(TEXTP t_ptr)
{
UBYTE str[30];
RING t;
block_copy(t_ptr,&t);
if (t_ptr->x1 == 0 && t_ptr->x2 == 0)
t.lines -= 1;
make_shortpath(t_ptr->filename, str, 30);
fill_ptext(blockinfo, BLONAME, str); /* Name mit Pfad */
ltoa(textring_bytes(&t, t_ptr->ending), str, 10);
fill_ptext(blockinfo, BLOGROSS, str); /* Größe in Bytes */
ltoa((&t)->lines, str, 10);
fill_ptext(blockinfo, BLOZEILE, str);
Arrow_mouse();
HndlDial(blockinfo, 0, FALSE, NULL, NULL);
Last_mouse();
kill_textring(&t);
}